﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WarriorRush.GameDynamics.SpecialAbilities;
using WarriorRush.GameDynamics.Effects;

namespace WarriorRush.GameDynamics.Characters
{
    public class WarriorCodex
    {
        public Dictionary<AbilityTypes, SpecialAbility> AbilityLookup;
        public Dictionary<EffectType, GameEffect> EffectLookup;
        public Dictionary<CharacterTypes, CharacterTraits> CharacterLookup;

        public WarriorCodex()
        {
            AbilityLookup = new Dictionary<AbilityTypes, SpecialAbility>{
                {AbilityTypes.Cleave, new Cleave()},
                {AbilityTypes.Evasion, new Evade()},
                {AbilityTypes.Silence, new Silence()},
                {AbilityTypes.Range, new Range()},
                {AbilityTypes.Enrage, new Enrage()},
                {AbilityTypes.Heal, new Heal()},
                {AbilityTypes.Pierce, new Pierce()},
                {AbilityTypes.Poison, new Poison()},
                {AbilityTypes.Shield, new Shield()},
                {AbilityTypes.Blind, new Blind()},
                {AbilityTypes.Daze, new Daze()},
                {AbilityTypes.WarCry, new WarCry{}},
                {AbilityTypes.Patrol, new Patrol()},
                {AbilityTypes.HardenSkin, new HardenSkin()},
                {AbilityTypes.Hasten, new Hasten()},
                
            };

            EffectLookup = new Dictionary<EffectType, GameEffect>{
                {EffectType.Blinded, new Blinding()},
                {EffectType.Enraged, new Raging()},
                {EffectType.Poisoned, new Poisoning()},
                {EffectType.Shielded, new Shielding()},
                {EffectType.Silenced, new Silencing()},
                {EffectType.Dazed, new Dazing()},
                {EffectType.Haste, new Hasting()}
            };

            CharacterLookup = new Dictionary<CharacterTypes,CharacterTraits>
            {
                {
                    CharacterTypes.Archer , 
                    new CharacterTraits(this){
                        OffensiveAbility = GetAbilityKVP(AbilityTypes.Range, 2),
                        DefensiveAbility= GetAbilityKVP(AbilityTypes.Daze,1),
                        Stats = new CharacterStats(10,1,3,1)
                       
                    }    
                },
                {
                    CharacterTypes.Barbarian , 
                    new CharacterTraits(this){
                        OffensiveAbility = GetAbilityKVP(AbilityTypes.Cleave, 1),
                        DefensiveAbility= GetAbilityKVP(AbilityTypes.Enrage,1),
                        Stats = new CharacterStats(10,1,2,1)
                    }    
                },
                {
                    CharacterTypes.Infantry , 
                    new CharacterTraits(this){
                        OffensiveAbility = GetAbilityKVP(AbilityTypes.Pierce, 1),
                        DefensiveAbility= GetAbilityKVP(AbilityTypes.Shield,1),
                        Stats = new CharacterStats(10,1,2,2)
                    }    
                },
                {
                    CharacterTypes.Brigand , 
                    new CharacterTraits(this){
                        OffensiveAbility = GetAbilityKVP(AbilityTypes.Blind, 1),
                        DefensiveAbility= GetAbilityKVP(AbilityTypes.Poison,1),
                        Stats = new CharacterStats(10,2,2,2)
                    }    
                },
                {
                    CharacterTypes.Medic , 
                    new CharacterTraits(this){
                        OffensiveAbility = GetAbilityKVP(AbilityTypes.Heal, 1),
                        DefensiveAbility= GetAbilityKVP(AbilityTypes.Silence, 1),
                        Stats = new CharacterStats(10,1,2,2)             
                    }    
                },
                {
                    CharacterTypes.Commander , 
                    new CharacterTraits(this){
                        OffensiveAbility = GetAbilityKVP(AbilityTypes.Patrol, 1),
                        DefensiveAbility = GetAbilityKVP(AbilityTypes.Evasion, 3),
                       
                        Stats = new CharacterStats(10,1,2,2)                  
                    }   
                },
                {
                    CharacterTypes.Gargoyle , 
                    new CharacterTraits(this){
                        OffensiveAbility = GetAbilityKVP(AbilityTypes.HardenSkin, 1),
                        DefensiveAbility = GetAbilityKVP(AbilityTypes.Hasten, 1),
                       
                        Stats = new CharacterStats(10,1,2,2)                  
                    }   
                }

            };

            foreach (var warrior in CharacterLookup)
            {
                warrior.Value.Type = warrior.Key;
            }

        }
        private KeyValuePair<AbilityTypes,int> GetAbilityKVP(AbilityTypes type, int power)
        {
            return new KeyValuePair<AbilityTypes, int>(type, power);
        }

        public CharacterClass GetCharacter(CharacterTypes type)
        {
            return CharacterLookup[type].GetCharacter();
        }
    }

    public class CharacterTraits
    {
        public KeyValuePair<AbilityTypes, int> OffensiveAbility;
        public KeyValuePair<AbilityTypes, int> DefensiveAbility;
        public CharacterStats Stats;
        public WarriorCodex Setup;
        public CharacterTypes Type;

        public CharacterTraits(WarriorCodex setup)
        {
            Setup = setup;
        }

        public CharacterClass GetCharacter()
        {
            var characterInstance = new CharacterClass(
                    Type,
                    Stats.GetInstance(),
                    Setup.AbilityLookup[OffensiveAbility.Key].GetInstance(OffensiveAbility.Value),
                    Setup.AbilityLookup[DefensiveAbility.Key].GetInstance(DefensiveAbility.Value)
                    );
            var offensiveEffect = characterInstance.OffensiveAbility.EfType;
            var defensiveEffect = characterInstance.DefensiveAbility.EfType;

            if (offensiveEffect != null)
            {
                var keys = characterInstance.OffensiveAbility.Effects.Select(f => f.Key);
                characterInstance.OffensiveAbility.Effects =
                    keys.ToDictionary(f => f, f => Setup.EffectLookup[f].GetInstance(OffensiveAbility.Value));
               

            }
            if (defensiveEffect != null)
            {

                var keys = characterInstance.DefensiveAbility.Effects.Select(f => f.Key);
                characterInstance.DefensiveAbility.Effects =
                    keys.ToDictionary(f => f, f => Setup.EffectLookup[f].GetInstance(DefensiveAbility.Value));
                
            }
            return characterInstance;
        
        }
    }
}
